home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
rpg
/
crossfir.000
/
crossfir
/
crossfire-0.92.4.client
/
item.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-21
|
10KB
|
421 lines
/*
CrossFire, A Multiplayer game for X-windows
Copryight (C) 1994 Mark Wedel
Copyright (C) 1992 Frank Tore Johansen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The author can be reached via e-mail to master@rahul.net
*/
#include <ctype.h> /* needed for isdigit */
#include <includes.h> /* prototypes most standard functions */
#include <item.h>
static item *free_items; /* the list of free (unused) items */
static item *player, *map; /* these lists contains rest of items */
/* player = pl->ob, map = pl->below */
#define NROF_ITEMS 50 /* how many items are reserved initially */
/* for the item spool */
/*
* new_item() returns pointer to new item which
* is allocated and initialized correctly
*/
static item *new_item ()
{
item *op = malloc (sizeof(item));
if (! op)
exit(0);
op->next = op->prev = NULL;
copy_name (op->name, "");
op->inv = NULL;
op->env = NULL;
op->tag = 0;
op->face = 0;
op->weight = 0;
op->magical = op->cursed = op->damned = 0;
op->unpaid = op->locked = op->applied = 0;
return op;
};
/*
* alloc_items() returns pointer to list of allocated objects
*/
static item *alloc_items (int nrof) {
item *op, *list;
int i;
list = op = new_item();
for (i=1; i<nrof; i++) {
op->next = new_item();
op->next->prev = op;
op = op->next;
}
return list;
}
/*
* free_items() frees all allocated items from list
*/
void free_all_items (item *op) {
item *tmp;
while (op) {
if (op->inv)
free_all_items (op->inv);
tmp = op->next;
free(op);
op = tmp;
}
}
/*
* Recursive function, used by locate_item()
*/
static item *locate_item_from_item (item *op, sint32 tag)
{
item *tmp;
for (; op; op=op->next)
if (op->tag == tag)
return op;
else if (op->inv && (tmp = locate_item_from_item (op->inv, tag)))
return tmp;
return NULL;
}
/*
* locate_item() returns pointer to the item which tag is given
* as parameter or if item is not found returns NULL
*/
item *locate_item (sint32 tag)
{
item *op;
if (tag == 0)
return map;
if ((op=locate_item_from_item(map->inv, tag)) != NULL)
return op;
if ((op=locate_item_from_item(player, tag)) != NULL)
return op;
return NULL;
}
/*
* remove_item() inserts op the the list of free items
* Note that it don't clear all fields in item
*/
void remove_item (item *op)
{
if (!op) return;
op->env->inv_updated = 1;
/* Do we really want to do this? */
if (op->inv)
remove_item_inventory (op);
if (op->prev) {
op->prev->next = op->next;
} else {
op->env->inv = op->next;
}
if (op->next) {
op->next->prev = op->prev;
}
/* add object to a list of free objects */
op->next = free_items;
if (op->next != NULL)
op->next->prev = op;
free_items = op;
op->prev = NULL;
op->env = NULL;
op->tag = 0;
}
/*
* remove_item_inventory() recursive frees items inventory
*/
void remove_item_inventory (item *op)
{
op->inv_updated = 1;
while (op->inv)
remove_item (op->inv);
}
/*
* add_item() adds item op to end of the inventory of item env
*/
static void add_item (item *env, item *op)
{
item *tmp;
for (tmp = env->inv; tmp && tmp->next; tmp=tmp->next)
;
op->next = NULL;
op->prev = tmp;
op->env = env;
if (!tmp) {
env->inv = op;
} else {
if (tmp->next)
tmp->next->prev = op;
tmp->next = op;
}
}
/*
* create_new_item() returns pointer to a new item, inserts it to env
* and sets its tag field and clears locked flag (all other fields
* are unitialized and may contain random values)
*/
item *create_new_item (item *env, sint32 tag)
{
item *op;
if (!free_items)
free_items = alloc_items (NROF_ITEMS);
op = free_items;
free_items = free_items->next;
if (free_items)
free_items->prev = NULL;
op->tag = tag;
op->locked = 0;
add_item (env, op);
return op;
}
#if 0
/*
* parse different flags (applied/worn/etc), but not flags which are
* part of a name (e.g. 'ring (Str +1)')
* (TODO: Insert strings to a configuration file)
*/
static void get_flags (item *op)
{
char *s1, *s2, buf[256];
s1 = op->name;
buf[0] = 0;
op->flags[0] = 0;
op->was_open = op->open;
op->open = 0;
op->applied = op->unpaid = op->magical = op->damned = op->cursed = 0;
while ((s2=strchr(s1, ' ')) != NULL) {
strncat (buf, s1, s2 - s1);
s1 = s2;
if (*(s2+1) == '(') {
if (strncmp (s2, " (magic)", 8) == 0) {
op->magical = 1;
strcat (op->flags, " (magic)");
s1 += 8;
} else if (strncmp (s2, " (worn)", 7) == 0) {
op->applied = 1;
strcat (op->flags, " (worn)");
s1 += 7;
} else if (strncmp (s2, " (wielded)", 10) == 0) {
op->applied = 1;
strcat (op->flags, " (wielded)");
s1 += 10;
} else if (strncmp (s2, " (damned)", 9) == 0) {
op->damned = 1;
strcat (op->flags, " (damned)");
s1 += 9;
} else if (strncmp (s2, " (cursed)", 9) == 0) {
op->cursed = 1;
strcat (op->flags, " (cursed)");
s1 += 9;
} else if (strncmp (s2, " (readied)", 10) == 0) {
op->applied = 1;
strcat (op->flags, " (readied)");
s1 += 10;
} else if (strncmp (s2, " (active)", 9) == 0) {
op->applied = 1;
strcat (op->flags, " (active)");
s1 += 9;
} else if (strncmp (s2, " (unpaid)", 9) == 0) {
op->unpaid = 1;
strcat (op->flags, " (unpaid)");
s1 += 9;
} else if (strncmp (s2, " (open)", 7) == 0) {
op->open = 1;
strcat (op->flags, " (open)");
s1 += 7;
} else {
strncat (buf, s2, 1);
s1 += 1;
}
#if 1 /* checking locked, but this really belongs to client size */
} else if (strncmp (s2, " *", 2) == 0) {
op->locked = 1;
strcat (op->flags, " *");
s1 += 2;
#endif
} else {
strncat (buf, s2, 1);
s1 += 1;
}
}
if (*s1)
strcat (buf, s1);
copy_name (op->name, buf);
}
#else
/*
* Hardcoded now, server could send these at initiation phase.
*/
enum {a_none, a_readied, a_wielded, a_worn, a_active, a_applied};
static char *apply_string[] = {
"", " (readied)", " (wielded)", " (worn)", " (active)", " (applied)"
};
#define F_APPLIED 0x000F
#define F_LOCATION 0x00F0
#define F_CLEAR_INV 0x0100
#define F_UNPAID 0x0200
#define F_MAGIC 0x0400
#define F_CURSED 0x0800
#define F_DAMNED 0x1000
#define F_OPEN 0x2000
#define F_NOPICK 0x4000
static void set_flag_string (item *op)
{
op->flags[0] = 0;
if (op->locked)
strcat (op->flags, " *");
if (op->apply_type) {
if (op->apply_type <= sizeof (apply_string) / sizeof(apply_string[0]))
strcat (op->flags, apply_string[op->apply_type]);
else
strcat (op->flags, " (undefined)");
}
if (op->open)
strcat (op->flags, " (open)");
if (op->damned)
strcat (op->flags, " (damned)");
if (op->cursed)
strcat (op->flags, " (cursed)");
if (op->magical)
strcat (op->flags, " (magic)");
if (op->unpaid)
strcat (op->flags, " (unpaid)");
}
static void get_flags (item *op, uint16 flags)
{
op->was_open = op->open;
op->open = flags & F_OPEN ? 1 : 0;
op->damned = flags & F_DAMNED ? 1 : 0;
op->cursed = flags & F_CURSED ? 1 : 0;
op->magical = flags & F_MAGIC ? 1 : 0;
op->unpaid = flags & F_UNPAID ? 1 : 0;
op->applied = flags & F_APPLIED ? 1 : 0;
op->apply_type = flags & F_APPLIED;
set_flag_string(op);
}
#endif
/*
* get_nrof() functions tries to get number of items from the item name
*/
static sint32 get_nrof(char *name)
{
static char *numbers[21] = {
"no ","a ","two ","three ","four ","five ","six ","seven ","eight ",
"nine ","ten ","eleven ","twelve ","thirteen ","fourteen ","fifteen ",
"sixteen ","seventeen ","eighteen ","nineteen ","twenty "
};
static char *numbers_10[10] = {
"zero ","ten ","twenty ","thirty ","fourty ","fifty ","sixty ",
"seventy ","eighty ","ninety "
};
sint32 nrof = 0;
int i;
if (isdigit (*name))
nrof = atol (name);
else if (strncmp (name, "a ", 2) == 0 || strncmp (name, "an ", 3) == 0)
nrof = 1;
else {
for (i=1; i<sizeof(numbers)/sizeof(numbers[0]); i++)
if (strncmp (name, numbers[i], strlen (numbers[i])) == 0) {
nrof = i;
break;
}
if ( !nrof ) {
for (i=1; i<sizeof(numbers_10)/sizeof(numbers_10[0]); i++)
if (strncmp(name, numbers_10[i], strlen(numbers_10[i])) == 0) {
nrof = i * 10;
break;
}
}
}
return nrof ? nrof : 1;
}
void set_item_values (item *op, char *name, sint32 weight, uint16 face,
uint16 flags)
{
if (!op) {
printf ("Error in set_item_values(): item pointer is NULL.\n");
return;
}
copy_name (op->name, name);
op->env->inv_updated = 1;
op->nrof = get_nrof(name);
op->weight = (float) weight / 1000;
op->face = face;
get_flags (op, flags);
}
void toggle_locked (item *op)
{
if (op->env->tag == 0)
return; /* if item is on the ground, don't lock it */
op->locked = !op->locked;
op->env->inv_updated = 1;
set_flag_string (op);
}
item *player_item ()
{
player = new_item();
return player;
}
item *map_item ()
{
map = new_item();
map->weight = -1;
return map;
}